import logging
import platform
import re
import time

from src.common.prj_path import get_abs_path
from src.common.utils import get_execute_cmd_result, get_platform_name, read_file, check_str_equal

LOG = logging.getLogger()


class ADB(object):
    platform_name = get_platform_name()

    @classmethod
    def adb_connect(cls, ip, port=5555):
        if cls.check_adb_is_connect(ip):
            LOG.debug('adb {} already connect'.format(ip))
            return
        cmd = 'adb connect {}:{}'.format(ip, port)
        get_execute_cmd_result(cmd)
        if cls.check_adb_is_connect(ip):
            LOG.info('adb connect {}:{} success'.format(ip, port))
        else:
            err_msg = 'adb connect {}:{} failed'.format(ip, port)
            LOG.error(err_msg)
            raise Exception(err_msg)

    @classmethod
    def check_adb_is_connect(cls, ip=None) -> bool:
        cmd = 'adb devices'
        result = get_execute_cmd_result(cmd)
        p = result.split('\n')[1:]
        devices = [str1.split('\t')[0] for str1 in p]
        if not ip:
            return bool(devices)
        else:
            return bool([device for device in devices if ip in device])

    @classmethod
    def get_adb_devices(cls):
        """"
        List of devices attached
        192.168.2.243:5555	device
        :return: 192.168.2.243:5555
        """
        cmd = 'adb devices'
        result = get_execute_cmd_result(cmd)
        p = result.split('\n')[1:]
        devices = [str1.split('\t')[0] for str1 in p]
        LOG.debug('adb devices\n\t{}'.format(devices))
        return devices

    @classmethod
    def wait_for_device(cls):
        cmd = "adb wait-for-device"
        get_execute_cmd_result("adb wait-for-device")
        LOG.debug('{} success'.format(cmd))

    @classmethod
    def tap(cls, x, y):
        cls.wait_for_device()
        cmd = "adb shell input tap {} {}".format(x, y)
        get_execute_cmd_result(cmd)
        LOG.debug('{} success'.format(cmd))
        time.sleep(1)

    @classmethod
    def dump_xml(cls, path):
        cls.wait_for_device()
        cmd = "adb shell uiautomator dump {}".format(path)
        output = get_execute_cmd_result(cmd)
        LOG.debug('{}\n\toutput: {}'.format(cmd, output))
        time.sleep(1)

    @classmethod
    def download_file(cls, src, dst):
        cls.wait_for_device()
        cmd = "adb pull {} {}".format(src, dst)
        output = get_execute_cmd_result(cmd)
        LOG.debug('{}\n\toutput: {}'.format(cmd, output))
        time.sleep(1)

    @classmethod
    def input_text(cls, text):
        cls.wait_for_device()
        cmd = "adb shell input text {}".format(text)
        get_execute_cmd_result(cmd)
        LOG.debug('{} success'.format(cmd))
        time.sleep(1)

    @classmethod
    def check_screen_is_locked(cls):
        cls.wait_for_device()
        map_dict = {'windows': 'findstr', 'linux': 'grep'}
        map_string = map_dict[ADB.platform_name]
        cmd = "adb shell dumpsys window policy | {} isStatusBarKeyguard".format(map_string)
        output = get_execute_cmd_result(cmd)
        locked_status = re.findall(r"isStatusBarKeyguard=(\w+)", output)[0]
        LOG.debug('{}\n\toutput: screen_is_locked={}'.format(cmd, locked_status))
        return locked_status == 'true'

    @classmethod
    def light_up_screen(cls):
        cmd = 'adb shell input keyevent 224'
        get_execute_cmd_result(cmd)
        LOG.debug('{} success'.format(cmd))

    @classmethod
    def swipe_to_unlock(cls):
        cmd = 'adb shell input swipe 300 1000 300 500'
        get_execute_cmd_result(cmd)
        LOG.debug('{} success'.format(cmd))

    @classmethod
    def swipe_to_show_notification(cls):
        cmd = 'adb shell input swipe 300 0 300 1500'
        get_execute_cmd_result(cmd)
        LOG.debug('{} success'.format(cmd))

    @classmethod
    def unlock_phone(cls):
        if cls.check_screen_is_locked():
            cls.light_up_screen()
            time.sleep(0.5)
        cls.swipe_to_unlock()
        time.sleep(0.5)

    @classmethod
    def get_notification(cls):
        if check_str_equal(ADB.platform_name, "Windows", match_case=False):
            notification_path = get_abs_path('output', 'notification.txt')
            download_notification_cmd = 'adb shell dumpsys notification > {}'.format(notification_path)
            get_execute_cmd_result(download_notification_cmd)
            pattern = re.compile(r'tickerText=(.*)')
            # pattern = re.compile(r"NotificationRecord(.*)pkg=(.*)")
            content = read_file(notification_path)
            result = pattern.findall(content)
            result = [item for item in result if item != 'null']
        elif check_str_equal(ADB.platform_name, "LINUX", match_case=False):
            cmd = "adb shell dumpsys notification |grep tickerText | grep  -v 'null'"
            result = get_execute_cmd_result(cmd)
        else:
            raise Exception('not support this system={}'.format(ADB.platform_name))
        if isinstance(result, list):
            result = ';'.join(result)
        LOG.debug('手机通知={}'.format(result))
        return result

    @classmethod
    def get_all_notification_package(cls):
        map_dict = {'windows': 'findstr', 'linux': 'grep'}
        map_string = map_dict[ADB.platform_name.lower()]
        cmd = 'adb shell dumpsys notification | {} NotificationRecord'.format(map_string)
        result = get_execute_cmd_result(cmd)
        if isinstance(result, list):
            result = ';'.join(result)
        pattern = re.compile(r'(?<=pkg=).*?(?=\s)')
        package_list = pattern.findall(result)
        LOG.debug('通知包名={}'.format(package_list))
        return package_list

    @classmethod
    def check_this_package_have_notification(cls, package_name):
        package_list = cls.get_all_notification_package()
        flag = package_name in package_list
        LOG.debug('if_have_notification={}'.format(flag))
        return flag

    @classmethod
    def check_package_name_running(self, package_name):
        map_dict = {'windows': 'findstr', 'linux': 'grep'}
        map_string = map_dict[ADB.platform_name.lower()]
        cmd = 'adb shell dumpsys activity activities | {} packageName'.format(map_string)
        result = get_execute_cmd_result(cmd)
        if isinstance(result, list):
            result = ';'.join(result)
        flag = package_name in result
        LOG.debug('{}包名是否在运行={}'.format(package_name, flag))
        return flag

    @classmethod
    def check_app_running_health(cls, package_name, activity_name):
        if not cls.check_package_name_running(package_name):
            LOG.warning('{} is not running'.format(package_name))
            cls.unlock_phone()
            cmd = 'adb shell am start {}/{}'.format(package_name, activity_name)
            get_execute_cmd_result(cmd)
            LOG.info('{} restart'.format(package_name))
        else:
            LOG.debug('{} is running'.format(package_name))


if __name__ == '__main__':
    ADB.adb_connect('192.168.2.243')

    # text = ADB.get_notification()
    # print(text)
    # print(ADB.check_package_name_running('qianniu'))


    ADB.swipe_to_show_notification()

